<script setup>
import { useRoute, useRouter } from 'vue-router'
import { ref, onMounted } from 'vue'
import io from 'socket.io-client'
import { Socket } from 'socket.io-client'
const videoflag = ref(false)

const roomId = localStorage.getItem('roomId')//房间号

const called = ref(false)//是否是接收方
const caller = ref(false)//是否是发送方
const calling = ref(false)//呼叫中
const communicating = ref(false)//视频通话中
const localVideo = ref()//video标签实例 播放本人的视频
const remoteVideo = ref()//video标签实例 播放对方的视频
const socketio = ref()//socket实例
const peer = ref()//RTCPeerConnection实例
const localStream = ref()//本地音视频流
const remoteStream = ref()//远程音视频流
let chatList=JSON.parse(localStorage.getItem('chatList'))


onMounted(() => {
    // 页面打开就会执行
    const socket = io('http://localhost:3000')//连接socket服务器
    //监听connectionSuccess后端的事件
    socket.on('connectionSuccess', () => {
        console.log('连接成功...')//前端顺利的连接好信令服务器
        // 向服务器发送一个房间的事件
        socket.emit('joinRoom', roomId)
    })

    socket.on('callRemote', () => {
        if (!caller.value) {//不是用户A
            called.value = true//接收方
            calling.value = true//视频通话中
        }
    })
    //用户A收到用户B同意视频请求
    socket.on('acceptCall', async () => {
        if (caller.value) {//是用户A 
            peer.value = new RTCPeerConnection()//RTCPeerConnection实现音视频实时通信的关键
            peer.value.addStream(localStream.value)//peer添加本地音视频流生成offer
            peer.value.onicecandidate = (event) => {// 通过监听onicecandidate事件来获取A的ICE候选信息
                if (event.candidate) {
                    // 发送ICE候选信息给用户B
                    socketio.value?.emit('sendCandidate', { candidate: event.candidate, roomId })
                }
            }
            // 接下来用户A和用户B就可以进行P2P通信流
            peer.value.onaddstream = (event) => {//监听onaddstream事件 用户A收到用户B的stream
                communicating.value = true//视频通话中
                calling.value = false//呼叫中停止中
                remoteStream.value = event.stream// 设置对方视频流
                remoteVideo.value.srcObject = event.stream
                remoteVideo.value.play()
            }
            //生成offer 生成用户A的SDP信息 将SDP信息发送给用户B
            const offer = await peer.value.createOffer({
                offerToReceiveAudio: 1,
                offerToReceiveVideo: 1
            })
            await peer.value.setLocalDescription(offer) // 在本地设置offer信息
            socketio.value?.emit('sendOffer', { offer, roomId })//发送offer给(信令服务器)用户B
        }
    })

    // 收到offer
    socket.on('sendOffer', async (offer) => {
        if (called.value) {//用户B
            console.log('收到offer', offer);//用户B收到用户A的SDP信息
            peer.value = new RTCPeerConnection()//用户B创建自己的RTCPeerConnection，peer添加本地音视频流生成offer
            const stream = await getLocalStream()//获取本地音视频流
            peer.value.addStream(stream)//添加本地音视频流
            // 添加ICE候选信息到peer
            peer.value.onicecandidate = (event) => {
                // console.log('用户B的ICE候选信息------', event.candidate)
                if (event.candidate) {
                    // 发送ICE候选信息给用户A
                    socketio.value.emit('sendCandidate', { candidate: event.candidate, roomId })
                }
            }

            // 接下来用户A和用户B就可以进行P2P通信流
            //监听onaddstream事件来获取对方的音视频流
            peer.value.onaddstream = (event) => {
                console.log('用户B收到用A的stream------', event.stream)
                communicating.value = true//视频通话中
                calling.value = false//视频通话中
                remoteStream.value = event.stream
                remoteVideo.value.srcObject = event.stream
                remoteVideo.value.play()
            }
            // 设置远程的SDP信息(描述信息)
            await peer.value.setRemoteDescription(offer)
            const answer = await peer.value.createAnswer({// 生成answer
                offerToReceiveAudio: 1,
                offerToReceiveVideo: 1
            })
            // console.log('用户B的answer------', answer);
            // 设置本地answer
            await peer.value.setLocalDescription(answer)
            // 发送answer给用户A
            socketio.value.emit('sendAnswer', { answer, roomId })
        }
    })

    // 用户A收到answer
    socket.on('sendAnswer', async (answer) => {
        if (caller.value) {//用户A
            // console.log('用户A收到answer', answer);
            // 设置远程的SDP信息(描述信息)
            await peer.value.setRemoteDescription(answer)
        }
    })
    // 添加candidate
    socket.on('sendCandidate', async (candidate) => {
        // console.log('candidate信息', candidate);
        // 添加ICE候选信息到peer
        await peer.value.addIceCandidate(candidate)
    })
    //挂断
    socket.on('hangUp', () => {
        console.log('挂断');
        // 关闭peer连接
        // peer.value.close()
        // 重置状态
        caller.value = false
        calling.value = false
        communicating.value = false
        // 重置视频流
        localStream.value = null
        remoteStream.value = null
        // 重置视频标签
        localVideo.value.srcObject = null
        remoteVideo.value.srcObject = null
    })

    // 用户A收到ICE候选信息
    socketio.value = socket
})





// 获取本地音视频流
const getLocalStream = async () => {
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true })
    localVideo.value.srcObject = stream
    localVideo.value.play()
    localStream.value = stream
    return stream
}

//发起方发起视频请求
const callRemote = async () => {
    videoflag.value = true
    console.log('发起方发起视频请求');
    // 用户A向用户B发起视频请求
    caller.value = true//表示当前用户是发起方
    calling.value = true//表示当前用户正在呼叫
    // 通过信令服务器向用户B发起视频请求
    // console.log(socketio.value);
    await getLocalStream()//获取本地音视频流
    socketio.value.emit('callRemote', roomId)//向服务器发送一个事件
}
//接收方同意视频请求
const acceptCall = () => {
    videoflag.value = true
    console.log('接收方同意视频请求');
    //通过信令服务器通知用户A
    socketio.value.emit('acceptCall', roomId)
}
//挂断视频
const hangUp = () => {
    console.log('挂断');
    //通过信令服务器通知用户A
    socketio.value.emit('hangUp', roomId)
    videoflag.value = false
}

const router = useRouter()
const ele = JSON.parse(localStorage.getItem('ele'))

const goTochatList = () => {
    router.push('/chatlist')


}
</script>

<template>
    <div style="height:'100vh'">

        <div class="titles" v-if="!videoflag">
            <img id="back" @click="router.go(-1)" src="@/assets/chattool/back.png" alt="">
            <p>{{ ele.name }}</p>
            <img id="threedian" src="@/assets/chattool/threedian.png" alt="">
        </div>
        <div id="content">
            <div id="box">
                <div id="box-video">
                    <video id="local-video"
                        ref="localVideo"></video>
                    <video id="remote-video"
                        ref="remoteVideo"></video>
                    <div id="text" v-if="caller && calling">
                        <p>等待对方接听...</p>
                        <img @click="hangUp" src="/refuse.png" alt="">
                    </div>
                    <div id="accept" v-if="called && calling">
                        <p>收到视频邀请...</p>
                        <div>
                            <img @click="hangUp" src="/refuse.png" alt="">
                            <img @click="acceptCall" src="/accept.png" alt="">
                        </div>
                    </div>
                </div>

            </div>
        </div>

        <div class="contents" v-if="!videoflag">
            <div v-for="item in chatList" :key="item._id" class="list1">
                <div v-for="ele in item.chatContent" :key="ele._id" class="list2">
                    <div class="block">
                        <div class="r">
                            <div class="right" v-show="ele.status">
                                <span>{{ ele.val }}</span>
                                <img :src="item.rightAvatar" alt="">
                            </div>
                        </div>
                        <div class="l">
                            <div class="left" v-show="!ele.status">
                                <img :src="item.leftAvatar" alt="">
                                <span>{{ ele.val }}</span>
                            </div>
                        </div>
    
    
                    </div>
                </div>
            </div>
        </div>

        <div id="input" v-if="!videoflag">
            <div class="one">
                <input />
                <div id="btn"><el-button>发送</el-button></div>
                <img @click="goTochatList" src="@/assets/chattool/riLine.png" alt="">
            </div>
            <div id="video" @click="callRemote">
                <img src="@/assets/chattool/video.png" alt="">
            </div>
        </div>
    </div>


</template>

<style scoped lang="scss">
.titles {
    position: relative;
    width: 390px;
    height: 44px;
    line-height: 26px;
    background-color: rgba(239, 239, 239, 1);
    color: rgba(16, 16, 16, 1);
    font-size: 18px;
    text-align: center;
    font-family: Roboto;
    border: 0px solid rgba(232, 232, 232, 1);

    #back {
        position: absolute;
        left: 4px;
        top: 10px;
        width: 24px;
        height: 24px;

    }

    #button20 {
        position: absolute;
        left: 28px;
        top: 13px;
        width: 29px;
        height: 18px;
        line-height: 17px;
        border-radius: 100px;
        background-color: rgba(206, 206, 206, 1);
        color: rgba(79, 79, 79, 1);
        font-size: 12px;
        text-align: center;
        font-family: Roboto;
    }

    p {
        position: absolute;
        left: 140px;
        top: 10px;

    }

    #threedian {
        position: absolute;
        left: 340px;
        top: 10px;
        width: 24px;
        height: 24px;
    }
}

#content {
    #box {
        height: 844px;
        width: 390px;
        z-index: 1500 !important;



        #box-video {

            position: relative;

            #local-video {
                object-fit: cover;
                width: 390px;
                height: 100vw;
                margin: 0;
                padding: 0;
                height: 100vh;
                position: absolute;
                
            }

            #remote-video {
                width: 100px;
                height: 180px;
                top: 0;
                right: 0;
                position: absolute;
                object-fit: cover;

            }

            #text {
                position: absolute;
                top: 600px;
                left: 160px;

                p {
                    color: #fff;
                    font-size: 20px;
                }

                img {
                    width: 100px;
                    height: 100px;
                }
            }

            #accept {
                z-index: 150;
                background: #fff;

                position: absolute;

                top: 600px;
                left: 160px;

                p {
                    color: #fff;
                    font-size: 20px;
                }

                img {
                    width: 100px;
                    height: 100px;
                }
            }
        }


    }

}
.contents {
    position: absolute;
    top: 60px;
    overflow-y: auto;
    width: 100vw;
    .list1 {
        .list2 {
            .block {
                display: flex;
                width: 100vw;
                justify-content: flex-start;
                box-sizing: border-box;
                .r {
                    width: 390px;
                    
                    .right {
                        float: right;
                        display: flex;
                        margin-top: 10px;
                        margin-right: 20px;
                        height: 60px;
                        line-height: 60px;

                        img {
                            border-radius: 15px;
                        }
                    }
                }

                .l {
                    .left {
                        display: flex;
                        margin-left: 20px;
                        margin-top: 10px;
                        width: 390px;
                        height: 60px;
                        line-height: 60px;


                        img {
                            border-radius: 15px;
                            margin: 0 5px;
                        }
                    }

                }




            }
        }
    }
}
#input {
    position: absolute;
    bottom: 0;
    width: 390px;
    height: 240px;
    line-height: 20px;
    background-color: rgba(209, 213, 219, 1);
    color: rgba(16, 16, 16, 1);
    font-size: 14px;
    text-align: center;
    font-family: Roboto;
    border: 1px solid rgba(239, 239, 239, 1);

    .one {
        display: flex;

        input {
            margin-left: 53px;
            margin-top: 26px;
            width: 200px;
            height: 40px;
            line-height: 20px;
            border-radius: 5px;
            background-color: rgba(255, 255, 255, 1);
            color: rgba(16, 16, 16, 1);
            font-size: 14px;
            text-align: center;
            font-family: Roboto;
        }

        #btn {
            width: 34px;
            height: 34px;
            margin-left: 12px;
            margin-top: 30px;
        }

        img {

            width: 34px;
            height: 34px;
            margin-left: 35px;
            margin-top: 30px;
        }
    }

    #video {
        margin-top: 30px;
        margin-left: 50px;
        background: #fff;
        width: 60px;
        height: 60px;
        border-radius: 12px;

        img {

            width: 40px;
            height: 40px;
            margin-left: 5px;
            margin-top: 10px;
        }
    }



}
</style>